#include <Windows.h>
#include <tchar.h>
#include <stdio.h>
#include <string>
#include <iostream>
using namespace std;

#ifdef _UNICODE
	#define _tostream	wostream
	#define _tout		wcout
#else
	#define _tostream	ostream
	#define _tout		cout
#endif

_tostream& operator<<(_tostream& out, const RECT& rtValue)
{
	out << _T("Rectangle[") 
		<< rtValue.left << _T(",")
		<< rtValue.top << _T(",")
		<< rtValue.right << _T(",")
		<< rtValue.bottom << _T("]");

	return out;
}

_tostream& operator<<(_tostream& out, const POINT& ptValue)
{
	out << _T("Point[") 
		<< ptValue.x << _T(",")
		<< ptValue.y << _T("]");

	return out;
}

void DemoRectAssign()
{
	_tout << _T("\nDemo Rect Assignment: ") << endl;
	_tout << "-------------------------------------------" << endl;

	RECT rtSrc;
	RECT rtDst;
	
	SetRectEmpty(&rtSrc);
	SetRect(&rtDst, 0, 0, 800, 480);      // set a new data to RECT Object
	GetWindowRect(GetDesktopWindow(), &rtSrc);
	 
	_tout << _T("After to set rect initialize value: ") << endl;
	_tout << "rtSrc - " << rtSrc << endl;
	_tout << "rtDst - " << rtDst << endl;
		
	CopyRect(&rtDst, &rtSrc);			// Set data from existing RECT object

	_tout << _T("After to Copy rect from a existing RECT object:") << endl;
	_tout << "rtSrc - " << rtSrc << endl;
	_tout << "rtDst - " << rtDst << endl;

	return;
}

void DemoRectDetermine()
{
	_tout << _T("\nDemo Rect Determine: ") << endl;
	_tout << "-------------------------------------------" << endl;

	RECT rtSrc = {0};
	RECT rtDst = {0};

	GetWindowRect(GetDesktopWindow(), &rtSrc);

	//--: empty
	_tout << rtSrc << _T(" is empty ?  ");
	IsRectEmpty(&rtSrc) ? _tout << _T("Yes") : _tout << _T("No");
	_tout << endl;

	_tout << rtDst << _T(" is empty ?  "); 
	IsRectEmpty(&rtDst) ? _tout << _T("Yes") : _tout << _T("No");
	_tout << endl;
	
	//--: equal
	_tout << rtSrc << _T(" is equal ")  << rtDst << _T(" ? ");
	EqualRect(&rtSrc, &rtDst)  ? _tout << _T("Yes") : _tout << _T("No");
	_tout << endl;

	POINT ptPoint = {100, 100};
	_tout << ptPoint << _T(" is in ") << rtSrc << _T(" ? ");
	PtInRect(&rtSrc, ptPoint) ? _tout << _T("Yes") : _tout << _T("No");
	_tout << endl;

	return;
}

void DemoRectMove()
{
	_tout << _T("\nDemo Rect Move & Zoom: ") << endl;
	_tout << "-------------------------------------------" << endl;

	RECT rtSrc = {0};
	RECT rtDst = {0};

	GetWindowRect(GetDesktopWindow(), &rtSrc);

	//-- Offset Rect
	{
		_tout << _T("Before Offset rect: ") << endl;
		_tout << rtSrc << endl;

		OffsetRect(&rtSrc, 10, 10);

		_tout << _T("After Offset rect: (OffsetRect(10, 10)") << endl;
		_tout << rtSrc << endl;

		OffsetRect(&rtSrc, -10, -10);
	}

	//--: Zoom Rect
	{
		_tout << _T("\nBefore Zoom rect: ") << endl;
		_tout << rtSrc << endl;

		InflateRect(&rtSrc, -10, -10);

		_tout << _T("After Zoom rect: (InflateRect(10, 10)") << endl;
		_tout << rtSrc << endl;

		InflateRect(&rtSrc, 10, 10);
	}
	return;
}

void DemoRectJoin()
{
	_tout << _T("\nDemo Rect Join: ") << endl;
	_tout << "-------------------------------------------" << endl;

	RECT rtSrc = {0};
	RECT rtDst = {0};
	SetRect(&rtSrc, 100, 100, 300, 300);
	RECT rtSrcList[] = { 
		{0, 0, 50, 50},  
		{0, 0, 800, 480},
		{100, 100, 200, 200},
		{0, 0, 200, 200},
		{150, 50, 200, 200},
		{250, 50, 300, 300}
	};

	//--: Intersect rect
	{
		for (int ii = 0; ii < sizeof(rtSrcList) / sizeof(*rtSrcList); ii++)
		{
			if (IntersectRect(&rtDst, &rtSrc, &rtSrcList[ii]))
			{
				_tout << rtSrcList[ii] << _T(" intersect to ") << rtSrc << _T("=>") << rtDst << endl;
			} else {
				_tout << rtSrcList[ii] << _T(" doesn't intersect to ") << rtSrc << _T("=>") << rtDst << endl;
			}
		}
	}

	//--: Union rect
	{
		for (int ii = 0; ii < sizeof(rtSrcList) / sizeof(*rtSrcList); ii++)
		{
			if (UnionRect(&rtDst, &rtSrc, &rtSrcList[ii]))
			{
				_tout << rtSrcList[ii] << _T(" union to ") << rtSrc << _T("=>") << rtDst << endl;
			} else {
				_tout << rtSrcList[ii] << _T(" doesn't union to ") << rtSrc << _T("=>") << rtDst << endl;
			}
		}
	}

	//--: Subtract rect
	{
		RECT rtSrcList[] = { 
			{100, 50, 200, 200},  
			{50, 100, 300, 200}
		};

		for (int ii = 0; ii < sizeof(rtSrcList) / sizeof(*rtSrcList); ii++)
		{
			if (SubtractRect(&rtDst, &rtSrcList[ii], &rtSrc))
			{
				_tout << rtSrcList[ii] << _T(" subtract to ") << rtSrc << _T("=>") << rtDst << endl;
			} else {
				_tout << rtSrcList[ii] << _T(" doesn't substract to ") << rtSrc << _T("=>") << rtDst << endl;
			}
		}
	}

	return;
}

int _tmain(int argc, TCHAR* argv[])
{
	DemoRectAssign();

	DemoRectDetermine();
	
	DemoRectMove();

	DemoRectJoin();

	system("pause");

	return 0;
}